stop_machine: Allow specified function to run on all CPUs.
authorKeir Fraser <keir@xen.org>
Fri, 14 Jan 2011 14:16:04 +0000 (14:16 +0000)
committerKeir Fraser <keir@xen.org>
Fri, 14 Jan 2011 14:16:04 +0000 (14:16 +0000)
Signed-off-by: Keir Fraser <keir@xen.org>
xen/common/stop_machine.c
xen/include/xen/stop_machine.h

index 31d5c6fff79844a46b4a00ce04444db5c6299ce4..9bf271452de25629d69aa3ed9182e528ede782b0 100644 (file)
@@ -61,6 +61,10 @@ static void stopmachine_set_state(enum stopmachine_state state)
     atomic_set(&stopmachine_data.done, 0);
     smp_wmb();
     stopmachine_data.state = state;
+}
+
+static void stopmachine_wait_state(void)
+{
     while ( atomic_read(&stopmachine_data.done) != stopmachine_data.nr_cpus )
         cpu_relax();
 }
@@ -101,16 +105,20 @@ int stop_machine_run(int (*fn)(void *), void *data, unsigned int cpu)
         tasklet_schedule_on_cpu(&per_cpu(stopmachine_tasklet, i), i);
 
     stopmachine_set_state(STOPMACHINE_PREPARE);
+    stopmachine_wait_state();
 
     local_irq_disable();
     stopmachine_set_state(STOPMACHINE_DISABLE_IRQ);
+    stopmachine_wait_state();
 
-    if ( cpu == smp_processor_id() )
-        stopmachine_data.fn_result = (*fn)(data);
     stopmachine_set_state(STOPMACHINE_INVOKE);
+    if ( (cpu == smp_processor_id()) || (cpu == NR_CPUS) )
+        stopmachine_data.fn_result = (*fn)(data);
+    stopmachine_wait_state();
     ret = stopmachine_data.fn_result;
 
     stopmachine_set_state(STOPMACHINE_EXIT);
+    stopmachine_wait_state();
     local_irq_enable();
 
     spin_unlock(&stopmachine_lock);
@@ -140,7 +148,8 @@ static void stopmachine_action(unsigned long cpu)
             local_irq_disable();
             break;
         case STOPMACHINE_INVOKE:
-            if ( stopmachine_data.fn_cpu == smp_processor_id() )
+            if ( (stopmachine_data.fn_cpu == smp_processor_id()) ||
+                 (stopmachine_data.fn_cpu == NR_CPUS) )
                 stopmachine_data.fn_result =
                     stopmachine_data.fn(stopmachine_data.fn_data);
             break;
index 7d4506869fa4225bded08868fafdb8ad5638a78d..c63da1b3093c79bfea7152e6113a03bdae0dfcc7 100644 (file)
@@ -5,7 +5,7 @@
  * stop_machine_run: freeze the machine on all CPUs and run this function
  * @fn: the function to run
  * @data: the data ptr for the @fn()
- * @cpu: the cpu to run @fn() on (or any, if @cpu == NR_CPUS).
+ * @cpu: the cpu to run @fn() on (or all, if @cpu == NR_CPUS).
  *
  * Description: This causes every other cpu to enter a safe point, with
  * each of which disables interrupts, and finally interrupts are disabled